<?php

namespace app\command;

use swoole_table;
use swoole_lock;

/**
 * 继承 swoole_table
 * Class SwooleTable
 * @package app\command
 */
class SwooleTable extends swoole_table
{
    // 创建锁
    private $lock = null;

    /**
     * 创建锁
     * @param $type
     */
    public function createLock($type = SWOOLE_MUTEX) {
        $this->lock = new swoole_lock($type);
    }

    /**
     * 开启锁
     * @return bool
     */
    public function lock() {
        if(is_null($this->lock)) {
            return true;
        }
        return $this->lock->lock();
    }

    /**
     * 关闭锁
     * @return bool
     */
    public function unlock() {
        if(is_null($this->lock)) {
            return true;
        }
        return $this->lock->unlock();
    }

    /**
     * 执行带锁操作
     * @param $function
     * @return mixed
     * @throws \Exception
     */
    public function lockFunc($function) {
        $this->lock();
        $result = false;
        try {
            $result = $function($this);
            $this->unlock();
        }catch (\Exception $e) {
            $this->unlock();
            throw $e;
        }
        return $result;
    }

    /**
     * 使用 lock 锁操作方式调用方法
     * @param $method
     */
    public function lockCall($method) {
        $params = func_get_args();
        array_shift($params);
        return $this->lockFunc(function() use($method,$params){
            return call_user_func_array([$this,$method],$params);
        });

    }

}
